const mongoose = require('mongoose')
mongoose.set('useCreateIndex', true)
const Model = require('../dbs/model/getCollection.js')
const LocationFenceSchema = require('../dbs/schema/locationFenceSchema.js')
const TriggerFenceRecordSchema = require('../dbs/schema/triggerFenceRecordSchema.js')
const util = require('../com/util.js')
const http = require("http");
let realStudent = null;
//处理电子围栏是否报警
process.on('message', async (json) => {
    //在这个内存中设置全局配置
    global.COM_CONFIG = json.globalConfig;
    let data = json.data;  
    if (!data) {
        process.exit(1);
    }
    let studentId = data.Student.id;
    let schools = data.studentRelation.schoolList;
    let schoolIds = [];
    //关于此学生的所有电子围栏
    let fenceArr = [];
    for (let j = 0; j < schools.length; j++) {
        schoolIds.push(schools[j].orgCode);
    }

    let LocationFenceModel = await Model.getComModel({
        dataBase: 'com_info',
        tableName: 'location_fence',
        schema: LocationFenceSchema
    });

    delete data.studentRelation;
    realStudent = JSON.parse(JSON.stringify(data));

    await new Promise((r, j) => {
        LocationFenceModel
            .find({
                "$and": [
                    {
                        "$or": [
                            {
                                studentId: studentId
                            },
                            {
                                schoolId: {
                                    $in: schoolIds
                                }
                            }
                        ]
                    },
                    {
                        "$or": [
                            {
                                coordinate: {
                                    $exists: true
                                }
                            },
                            {
                                cirCoordinate: {
                                    $exists: true
                                }
                            }
                        ]
                    },
                    {
                        property: {
                            $exists: true
                        }
                    },
                    {
                        useFence: true
                    }
                ]
            })
            .exec((err, doc) => {
                fenceArr = doc;
                return r();
            });
    });
    // console.log('此学生电子围栏');
    // console.log(fenceArr)

    //赛选已经触发的报警的电子围栏/关于学生的所有电子围栏个数
    let alarmFence = [];
    let fenceLen = fenceArr.length;
    let cooJson = {
        len: fenceLen,
        alarmFence: alarmFence,
        locationFenceModel: LocationFenceModel,
        cooArr: [Number(data.Gps[0].Longitude), Number(data.Gps[0].Latitude)],
        student: util._delOthLocation(data),
        schools: schoolIds
    };
    for (let i = 0; i < fenceLen; i++) {
        let fence = fenceArr[i];
        if (fence.coordinate) {
            //多边形围栏坐标判断报警
            judgeCoo(cooJson, JSON.parse(JSON.stringify(fence)));
        } else if (fence.cirCoordinate) {
            //圆形围栏坐标判断报警
            judgeCirCoo(cooJson, JSON.parse(JSON.stringify(fence)));
        }
    }
});

//目前已经处理了的电子围栏个数
let nowHandleLne = 0;

/**
 * 多边形电子围栏判断是否在圈内
 * @param {*} json 
 */
let judgeCoo = async (json, fence) => {
    let LocationFenceModel = json.locationFenceModel;
    //学生现在的经纬度
    let cooArr = json.cooArr;

    LocationFenceModel.find({
        _id: fence._id,
        coordinate:
        {
            $geoIntersects:
            {
                $geometry: {
                    "type": "Point",
                    "coordinates": cooArr
                }
            }
        }
    }).exec((error2, doc) => {
        if (doc[0] && (doc[0].coordinate.coordinates.length > 0)) {
            //在本圈内
            fence.locaStatus = 'in';
        } else {
            //在本圈外
            fence.locaStatus = 'out';
        }
        handleAlarm(json, fence);
    });

};


/**
 * 家长圆形电子围栏判断是否在圈内
 * @param {*} json 
 */
let judgeCirCoo = async (json, fence) => {
    //学生现在经纬度/即将要处理的家长围栏
    let cooArr = json.cooArr;
    let realDis = util._getDisance(cooArr[1], cooArr[0], fence.cirCoordinate.latitude, fence.cirCoordinate.longitude);

    if (realDis <= fence.cirCoordinate.r) {
        //在圈内
        fence.locaStatus = 'in';
    } else {
        //在圈外
        fence.locaStatus = 'out';
    }
    handleAlarm(json, fence);
};


/**
 * 根据圈内还是圈外结合property来处理是否触发了此电子围栏的报警
 * @param {*} json 
 * @param {*} fence 
 */
let handleAlarm = async (json, fence) => {
    if (fence.locaStatus == 'in') {
        if (fence.property && fence.property.in) {
            //有可能是进入圈内触发
            let next = false;
            if (!fence.property.in.preStatus || fence.property.in.preStatus != 'in') {
                next = true;
            }
            //有触发报警的嫌疑
            if (next) {
                //判断进入圈内的次数是否达标，达标则报警
                fence.property.in.triggerCount += 1;
                if (fence.property.in.triggerCount >= fence.property.in.proCount) {
                    //报警
                    fence.student = json.student;
                    json.alarmFence.push(fence);
                    fence.property.in.triggerCount = 0;
                }
            }
            fence.property.in.preStatus = 'in';
        }
        if (fence.property && fence.property.out) {
            fence.property.out.preStatus = 'in';
        }
    }

    if (fence.locaStatus == 'out') {
        if (fence.property && fence.property.out) {
            //有可能是出圈触发
            let next = false;
            if (!fence.property.out.preStatus || fence.property.out.preStatus != 'out') {
                next = true;
            }
            //有触发报警的嫌疑
            if (next) {
                //判断进入圈内的次数是否达标，达标则报警
                fence.property.out.triggerCount += 1;
                if (fence.property.out.triggerCount >= fence.property.out.proCount) {
                    //报警
                    fence.student = json.student;
                    json.alarmFence.push(fence);
                    fence.property.out.triggerCount = 0;
                }
            }
            fence.property.out.preStatus = 'out';
        }
        if (fence.property && fence.property.in) {
            fence.property.in.preStatus = 'out';
        }
    }

    //更新本次位置，方便下次确定是不是继续在圈内/外
    await new Promise((r, j) => {
        json.locationFenceModel
            .updateOne(
                { '_id': fence._id },
                { property: fence.property }
            )
            .exec((err, doc) => {
                return r();
            });
    });

    if (json.len <= ++nowHandleLne) {
        //扫描完所有的电子围栏，已经赛选出了触发了哪些围栏，可以报警了
        // console.log('报警的所有电子围栏');
        // console.log(json.alarmFence);

        //触发的电子围栏条数/已经保存的触发电子围栏记录条数
        let alarmLen = json.alarmFence.length;
        let fenceRecordLen = 0;
        if (alarmLen > 0) {
            let stu = JSON.parse(JSON.stringify(json.alarmFence[0].student));
            stu.schools = json.schools;
            //触发电子围栏报警推送消息
            await post({
                url: global.COM_CONFIG.activitiService.fenceSos,
                data: JSON.stringify({
                    'student': stu,
                    'fenceList': json.alarmFence
                })
            });

            //存触发电子围栏记录
            let TriggerFenceRecordModel = await Model.getComModel({
                dataBase: 'com_info',
                tableName: 'trigger_fence_record',
                schema: TriggerFenceRecordSchema
            });
            await new Promise((r, j) => {
                let studentId=realStudent.Student.id;
                for (let i = 0; i < alarmLen; i++) {
                    let alFen=JSON.parse(JSON.stringify(json.alarmFence[i]));
                    delete alFen.student;
                    new TriggerFenceRecordModel({
                        studentId:studentId,
                        location: realStudent,
                        fence: alFen,
                        fenceId:alFen._id
                    }).save((err, doc) => {
                        if (++fenceRecordLen >= alarmLen) {
                            return r();
                        }
                    });
                }
            });
        }
        //退出此进程
        process.exit(1);
    }
};

let post = async (json) => {
    try {
        return await new Promise((r, j) => {
            let opt = json.opt ? json.opt : { method: 'POST' };
            let req = http.request(json.url, opt, function (res) {
                res.setEncoding('utf-8');
                res.on('data', function (data) {
                    return r(data);
                });
                res.on('error', function (e) {
                    console.log("请求其他服务失败:", e);
                    return r(false);
                });
            });
            req.on('error', function (e) {
                console.log("请求其他服务失败:", e);
                return r(false);
            })
            if (json.data) {
                req.write(json.data);
            }
            req.end();
        });
    } catch (e) { console.log('有错'); console.log(e); return false; }
};

